package com.dlc.apk.core

import com.dlc.apk.util.LogPlus
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

class ShipmentTaskHandler private constructor() {

    private var taskQueue: ArrayBlockingQueue<ShipmentTask> = ArrayBlockingQueue(100)
    private var countDownLatch: CountDownLatch? = null

    var lastShipmentTask: ShipmentTask? = null //最后成功的任务

    fun put(shipmentTask: ShipmentTask) {
        taskQueue.offer(shipmentTask)
    }

    fun handleTask(shipmentImpl: IShipment, shipmentTaskCallback: IShipmentTaskCallback) {
        Thread {
            try {
                while (true) {
                    val shipmentTask = taskQueue.take() ?: continue
                    if (countDownLatch == null || countDownLatch!!.count == 0L) {
                        countDownLatch = CountDownLatch(1)
                    }
                    try {
                        shipmentImpl.startShipment(shipmentTask)
                    } catch (t: Throwable) {
                        shipmentTaskCallback.onFailed(shipmentTask, t.message ?: "出货异常")
                    }
                    val startTime = System.currentTimeMillis()
                    val checkDeviceStatusDuration = 1000 * 7 * 2
                    var retryStartDeviceTimes = 2
                    var isShipmentSuccess = false
                    var lastRetryTime = startTime
                    while (System.currentTimeMillis() - startTime <= checkDeviceStatusDuration) {
                        Thread.sleep(100L)
                        val isShipmentResultSuccess = shipmentImpl.checkIsShipmentSuccessed(shipmentTask)
                        if (isShipmentResultSuccess) {
                            isShipmentSuccess = true
                            break
                        }

                        if (retryStartDeviceTimes > 0 && System.currentTimeMillis() - lastRetryTime >= 1000 * 7) {
                            LogPlus.e("###重试->$shipmentTask")
                            lastRetryTime = System.currentTimeMillis()
                            retryStartDeviceTimes--
                            shipmentImpl.startShipment(shipmentTask)
                        }
                    }
                    if (isShipmentSuccess) {
                        shipmentTaskCallback.onSuccess(shipmentTask)
                        shipmentTask.shipmentTaskCallback?.onSuccess(shipmentTask)
                        //更新"任务"中成功的时间
                        shipmentTask.shipmentTime = System.currentTimeMillis()
                        //任务完成
                        doCompleteTaskAndStartNext()
                    } else {
                        shipmentTaskCallback.onFailed(shipmentTask, "超时未能出货完成")
                        shipmentTask.shipmentTaskCallback?.onFailed(shipmentTask, "超时未能出货完成")
                        //任务完成 继续处理下一个任务
                        doCompleteTaskAndStartNext()
                    }
                    //阻塞等待流程任务完成 超过一定时间则强制结束
                    countDownLatch?.await(2, TimeUnit.MINUTES)
                    LogPlus.e("###本次任务完成### startDeviceTask->${shipmentTask}")
                    //记录最后任务 后台需要带上订单号上报
                    this.lastShipmentTask = shipmentTask
                }
            } catch (e: Throwable) {
                e.printStackTrace()
                LogPlus.e("处理任务线程异常,${LogPlus.getStackTraceInfo(e)}")
            }
            /*停止处理任务*/
            LogPlus.e("###处理任务线程已停止")
        }.start()
    }

    fun doCompleteTaskAndStartNext() {
        countDownLatch?.countDown()
    }

    class InstanceHolder {
        companion object {
            val INSTANCE: ShipmentTaskHandler = ShipmentTaskHandler()
        }
    }

    companion object {
        fun getInstance(): ShipmentTaskHandler {
            return InstanceHolder.INSTANCE
        }
    }

    data class ShipmentTask(val flowNo: Int, var cargoNumberType: Int, var actionCargoRowNumberOrNo1: Int, var actionCargoColumnNumber1: Int, var actionCargoRowNumberOrNo2: Int, var actionCargoColumnNumber2: Int, var actionCargoRowNumberOrNo3: Int, var actionCargoColumnNumber3: Int, var actionCargoRowNumberOrNo4: Int, var actionCargoColumnNumber4: Int, var actionCargoRowNumberOrNo5: Int, var actionCargoColumnNumber5: Int, var maxActionTime: Int, var pickTimeOut: Int, var theftBaffleTimeout: Int, var attachData: Any? = null, var shipmentTime: Long = 0, var errCode: Int = -1, var firstShipmentResult: Int, val shipmentTaskCallback: IShipmentTaskCallback? = null)

    interface IShipmentTaskCallback {
        fun onSuccess(shipmentTask: ShipmentTask)
        fun onFailed(shipmentTask: ShipmentTask, msg: String = "")
    }

    interface IShipment {
        /*发送出货命令*/
        fun startShipment(shipmentTask: ShipmentTask)

        /*检查是否已出货*/
        fun checkIsShipmentSuccessed(shipmentTask: ShipmentTask): Boolean
    }
}